package com.lb.bs.client.manager;


import com.lb.bs.client.annotation.SingletonMark;
import com.lb.bs.client.beans.CoreBean;
import com.lb.bs.client.repository.ScanStaticModel;
import com.lb.bs.client.config.StaticConfig;
import com.lb.bs.client.repository.StoreCenter;
import com.lb.bs.client.factory.SingletonFactory;
import com.lb.bs.client.processor.beans.ProcessorBean;
import com.lb.bs.client.processor.enums.ProcessorType;
import com.lb.bs.client.processor.mgr.ProcessorMgr;
import com.lb.bs.client.util.IPUtil;
import com.lb.bs.client.serialize.SerializationHolder;
import com.lb.bs.client.serialize.SerializationInterface;
import com.lb.bs.client.zookeeper.FetchMgr;
import com.lb.bs.client.zookeeper.ZKMgr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * program: LB-BS-Client
 * author: bsworld.xie
 * create: 2019-11-28 17:35
 * description:
 */
@SingletonMark
public class CoreMgr<T> {
    private static final Logger logger = LoggerFactory.getLogger(CoreMgr.class);

    private static  CoreMgr coreMgr;

    private ScanStaticModel scanStaticModel;


    private List<ProcessorBean<ScanStaticModel>> processorBeans = new ArrayList<>();

    private ProcessorMgr<ScanStaticModel> processorMgr;

    private ZKMgr zkMgr;

    private FetchMgr fetchMgr;

    private SerializationInterface serializationInterface;

    public CoreMgr(CoreBean coreBean) {

        this.scanStaticModel = coreBean.getScanStaticModel();

        initMgr(coreBean);

        initStaticEvent();
        /**
         *
         * 初始化地址信息
         * */
        StoreCenter.getInstance().setLocalAddress(IPUtil.getLocalAddress());

    }

    public void runStaticEvent() {
        for (ProcessorBean<ScanStaticModel> processorBean : processorBeans) {
            processorMgr.route(processorBean);
        }
    }

    public void close() {
        processorMgr.close();
        zkMgr.close();
    }


    private void initMgr(CoreBean coreBean) {

        //初始化序列化方式
        serializationInterface = SerializationHolder.getHolder();
        /**
         *
         * 初始化zk连接相关
         * */
        this.zkMgr = ZKMgr.getInstance(coreBean.getStaticConfig().getZkHost(), coreBean.getStaticConfig().getNameSpace());

        /**
         *
         *
         * 初始化fetchMgr相关
         * */

        this.fetchMgr = SingletonFactory.getInstance(FetchMgr.class);

        /**
         *
         * 初始化processor处理器
         * */
        this.processorMgr = SingletonFactory.getInstance(ProcessorMgr.class);
    }


    /**
     * 初始化静态事件
     */


    private void initStaticEvent() {

        /**
         * 第一步，构造本地的配置信息
         */
        processorBeans.add(new ProcessorBean<>(scanStaticModel, ProcessorType.FIRST_TO_ITEM_BEAN));
        processorBeans.add(new ProcessorBean<>(scanStaticModel, ProcessorType.FIRST_TO_INSTANCE));

        /**
         * 第二步，构造回调相关信息，初始化灰度相关信息
         */
        processorBeans.add(new ProcessorBean<>(scanStaticModel, ProcessorType.SECOND_SYNC_UPDATE_CALL_BACK));
        processorBeans.add(new ProcessorBean<>(scanStaticModel, ProcessorType.SECOND_INIT_GRAY_INIT));
        /**
         *
         *第三步，同步远程信息
         * */
        processorBeans.add(new ProcessorBean<>(scanStaticModel, ProcessorType.THIRD_WATCH_REMOTE_RELOAD));
    }


    public ZKMgr getZkMgr() {
        return zkMgr;
    }

    public FetchMgr getFetchMgr() {
        return fetchMgr;
    }

    public SerializationInterface getSerializationInterface() {
        return serializationInterface;
    }

    public ProcessorMgr<ScanStaticModel> getProcessorMgr() {
        return processorMgr;
    }

   public static CoreMgr getHolder(ScanStaticModel scanStaticModel, StaticConfig staticConfig) {

        coreMgr =  SingletonFactory.getInstanceWithConstructor(CoreMgr.class, new CoreBean(scanStaticModel, staticConfig));
        return coreMgr;
    }
}
